package com.maxd.service.selfOrder;

import com.gexin.fastjson.JSON;
import com.maxd.adapter.LoginUserHolder;
import com.maxd.bean.order.DeductPointRes;
import com.maxd.bean.order.PartnerInfo;
import com.maxd.bean.order.PointPayReq;
import com.maxd.component.sequence.SeqTools;
import com.maxd.constants.PPointScene;
import com.maxd.constants.PayScene;
import com.maxd.constants.PointScene;
import com.maxd.error.DescribeException;
import com.maxd.error.ExceptionEnum;
import com.maxd.error.Result;
import com.maxd.error.ResultUtil;
import com.maxd.model.*;
import com.maxd.modules.selfshop.merchants.entity.SelfMerchantApply;
import com.maxd.modules.selfshop.merchants.entity.SelfStore;
import com.maxd.modules.selfshop.merchants.respository.SelfMarginJpaRepository;
import com.maxd.modules.selfshop.merchants.respository.SelfMerchantApplyJpaRepository;
import com.maxd.modules.selfshop.merchants.respository.SelfStoreJpaRepository;
import com.maxd.modules.selfshop.merchants.service.SelfMarginService;
import com.maxd.modules.selfshop.merchants.service.SelfStoreService;
import com.maxd.respository.OrderPartnerInfoRepository;
import com.maxd.respository.PointRecordRepository;
import com.maxd.respository.common.CommonRepository;
import com.maxd.respository.money.MoneyDetailsJpaRepository;
import com.maxd.respository.selfCoupon.SelfCouponUserJpaRepository;
import com.maxd.respository.selfGoods.GoodsJpaRepository;
import com.maxd.respository.selfGoodsSku.SelfGoodsSkuJpaRepository;
import com.maxd.respository.selfGoodsVirtual.SelfGoodsVirtualJpaRepository;
import com.maxd.respository.selfGroup.SelfGroupJpaRepository;
import com.maxd.respository.selfGroupPink.SelfGroupPinkJpaRepository;
import com.maxd.respository.selfGroupSku.SelfGroupSkuJpaRepository;
import com.maxd.respository.selfOrder.OrdersJpaRepository;
import com.maxd.respository.selfOrder.OrdersRepository;
import com.maxd.respository.selfOrderRelation.OrdersRelationJpaRepository;
import com.maxd.respository.selfOrderRemind.SelfOrdersRemindJpaRepository;
import com.maxd.respository.selfSeckill.SelfSeckillJpaRepository;
import com.maxd.respository.userinfo.UserJpaRepository;
import com.maxd.respository.userinfo.UserRepository;
import com.maxd.service.jifen.IJiFenService;
import com.maxd.service.message.IMessageService;
import com.maxd.service.money.IMoneyDetailsService;
import com.maxd.service.partner.IPartnerService;
import com.maxd.service.pay.IPayRecordService;
import com.maxd.service.selfAliPay.SelfAliPayService;
import com.maxd.service.selfGoods.GoodsService;
import com.maxd.service.selfGoodsSku.SelfGoodsSkuService;
import com.maxd.service.selfGoodsVirtual.SelfGoodsVirtualService;
import com.maxd.service.selfGroupPink.SelfGroupPinkService;
import com.maxd.service.selfOrderRelation.OrdersRelationService;
import com.maxd.service.selfWXPay.SelfWXService;
import com.maxd.service.userinfo.IUserService;
import com.maxd.service.wx.AccountTokenServiceImpl;
import com.maxd.utils.AssertUtil;
import com.maxd.utils.DateUtil;
import com.maxd.utils.JsonUtils;
import com.maxd.utils.SeqUtils;
import com.maxd.utils.excel.ExcelData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrdersServiceImpl implements OrdersService {
    @Autowired
    private OrdersRepository ordersRepository;
    @Autowired
    private OrdersJpaRepository jpaRepository;
    @Autowired
    private OrdersRelationService ordersRelationService;
    @Autowired
    private OrdersRelationJpaRepository ordersRelationJpaRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private UserJpaRepository userJpaRepository;
    @Autowired
    private MoneyDetailsJpaRepository moneyDetailsJpaRepository;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private SelfAliPayService selfAliPayService;
    @Autowired
    private SelfWXService selfWXService;
    @Autowired
    private IJiFenService jiFenService;
    @Autowired
    private CommonRepository commonRepository;
    @Autowired
    private SelfOrdersRemindJpaRepository selfOrdersRemindJpaRepository;
    @Autowired
    private SelfGoodsSkuService skuService;
    @Autowired
    private SelfGroupPinkService groupPinkService;
    @Autowired
    private SelfGroupJpaRepository groupJpaRepository;
    @Autowired
    private SelfGroupSkuJpaRepository groupSkuJpaRepository;
    @Autowired
    private IUserService userService;
    @Autowired
    private IMessageService iMessageService;
    @Autowired
    private SelfCouponUserJpaRepository couponUserJpaRepository;
    @Autowired
    private SelfGoodsVirtualService selfGoodsVirtualService;
    @Autowired
    private SelfStoreService selfStoreService;
    @Autowired
    private SelfStoreJpaRepository selfStoreJpaRepository;
    @Autowired
    private SelfMerchantApplyJpaRepository selfMerchantApplyJpaRepository;
    @Autowired
    private SelfMarginService selfMarginService;
    @Autowired
    private SelfMarginJpaRepository selfMarginJpaRepository;
    @Autowired
    private SelfGroupPinkJpaRepository selfGroupPinkJpaRepository;
    @Autowired
    private IMoneyDetailsService iMoneyDetailsService;
    @Autowired
    private SelfGoodsVirtualJpaRepository goodsVirtualJpaRepository;

    @Autowired
    private IPayRecordService payRecordService;

    @Autowired
    private GoodsJpaRepository goodsJpaRepository;
    @Autowired
    private SelfGroupJpaRepository selfGroupJpaRepository;
    @Autowired
    private SelfSeckillJpaRepository selfSeckillJpaRepository;

    @Autowired
    private SelfGoodsSkuJpaRepository selfGoodsSkuJpaRepository;

    @Autowired
    private OrderPartnerInfoRepository orderPartnerInfoRepository;

    @Autowired
    private IPartnerService partnerService;

    @Autowired
    private PointRecordRepository pointRecordRepository;

    @Value("${classes.partner}")
    private String partnerTypeId;

    @Value("${classes.instructor}")
    private String instructorTypeId;

    @Value("${goods.instructor}")
    private String instructorGoodsId;

    @Value("${deduct.percents}")
    private String percentList;

    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(true);


    /**
     * 订单列表
     *
     * @param page
     * @param size
     * @param orderNum
     * @param status
     * @return
     */
    @Override
    public Result findAll(Integer page, Integer size, String orderNum, String status, Integer orderType, String title, String mobile, Long storeId, Integer isExpress, String startTime, String endTime) {
        //根据时间排序
        Pageable pageable = PageRequest.of(page, size, Sort.by(new Sort.Order(Sort.Direction.DESC, "createAt")));
        // 构造自定义查询条件
        Specification<Orders> queryCondition = new Specification<Orders>() {
            @Override
            public Predicate toPredicate(Root<Orders> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();
                if (StringUtils.isNotEmpty(orderNum)) {
                    predicateList.add(criteriaBuilder.equal(root.get("orderNum"), orderNum));
                }
                if (!"0".equals(status)) {
                    predicateList.add(criteriaBuilder.equal(root.get("status"), status));
                }
                if (orderType != 0) {
                    predicateList.add(criteriaBuilder.equal(root.get("orderType"), orderType));
                }
                if (StringUtils.isNotEmpty(title)) {
                    predicateList.add(criteriaBuilder.like(root.get("title"), "%" + title + "%"));
                }
                if (StringUtils.isNotEmpty(mobile)) {
                    predicateList.add(criteriaBuilder.equal(root.get("mobile"), mobile));
                }
                if (storeId != null) {
                    predicateList.add(criteriaBuilder.equal(root.get("storeId"), storeId));
                } else {
                    predicateList.add(criteriaBuilder.isNull(root.get("storeId")));
                }
                if (storeId != null) {
                    predicateList.add(criteriaBuilder.equal(root.get("storeId"), storeId));
                } else {
                    predicateList.add(criteriaBuilder.isNull(root.get("storeId")));
                }
                if (isExpress != null) {
                    predicateList.add(criteriaBuilder.equal(root.get("isExpress"), isExpress));
                }
                if (StringUtils.isNotEmpty(startTime)) {
                    predicateList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createAt"), startTime));
                }
                if (StringUtils.isNotEmpty(endTime)) {
                    predicateList.add(criteriaBuilder.lessThanOrEqualTo(root.get("createAt"), endTime));
                }
                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
        return ResultUtil.success(jpaRepository.findAll(queryCondition, pageable));
    }


    @Override
    public ExcelData listExcel(String orderNum, String status, Integer orderType, String title, String mobile, Long storeId, Integer isExpress, String startTime, String endTime) {
        // 构造自定义查询条件
        // 构造自定义查询条件
        Specification<Orders> queryCondition = new Specification<Orders>() {
            @Override
            public Predicate toPredicate(Root<Orders> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();
                if (StringUtils.isNotEmpty(orderNum)) {
                    predicateList.add(criteriaBuilder.equal(root.get("orderNum"), orderNum));
                }
                if (!"0".equals(status)) {
                    predicateList.add(criteriaBuilder.equal(root.get("status"), status));
                }
                if (orderType != 0) {
                    predicateList.add(criteriaBuilder.equal(root.get("orderType"), orderType));
                }
                if (StringUtils.isNotEmpty(title)) {
                    predicateList.add(criteriaBuilder.like(root.get("title"), "%" + title + "%"));
                }
                if (StringUtils.isNotEmpty(mobile)) {
                    predicateList.add(criteriaBuilder.equal(root.get("mobile"), mobile));
                }
                if (storeId != null) {
                    predicateList.add(criteriaBuilder.equal(root.get("storeId"), storeId));
                } else {
                    predicateList.add(criteriaBuilder.isNull(root.get("storeId")));
                }
                if (storeId != null) {
                    predicateList.add(criteriaBuilder.equal(root.get("storeId"), storeId));
                } else {
                    predicateList.add(criteriaBuilder.isNull(root.get("storeId")));
                }
                if (isExpress != null) {
                    predicateList.add(criteriaBuilder.equal(root.get("isExpress"), isExpress));
                }
                if (StringUtils.isNotEmpty(startTime)) {
                    predicateList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createAt"), startTime));
                }
                if (StringUtils.isNotEmpty(endTime)) {
                    predicateList.add(criteriaBuilder.lessThanOrEqualTo(root.get("createAt"), endTime));
                }
                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
        List<Orders> all = jpaRepository.findAll(queryCondition);
        ExcelData data = new ExcelData();
        data.setName("订单列表");
        List<String> titles = new ArrayList();
        titles.add("商品图片");
        titles.add("商品标题");
        titles.add("商品规格");
        titles.add("商品个数");
        titles.add("订单备注");
        titles.add("订单类型");
        titles.add("订单号");
        titles.add("收货人");
        titles.add("手机号");
        titles.add("详细地址");
        titles.add("商品价格");
        titles.add("支付金额");
        titles.add("佣金");
        titles.add("退款原因");
        titles.add("驳回原因");
        titles.add("支付方式");
        titles.add("创建时间");
        titles.add("付款时间");
        titles.add("收货时间");
        titles.add("订单状态");
        data.setTitles(titles);
        List<List<Object>> rows = new ArrayList();
        for (Orders orders : all) {
            List<Object> row = new ArrayList();
            row.add(orders.getImg());
            row.add(orders.getTitle());
            row.add(StringUtils.isEmpty(orders.getDetailJson()) ? "无" : orders.getDetailJson());
            row.add(orders.getNumber());
            row.add(StringUtils.isEmpty(orders.getDescrition()) ? "未填写" : orders.getDescrition());
            //1普通订单 2拼团订单 3秒杀订单 4积分订单
            if (orders.getOrderType() == 1) {
                row.add("普通订单");
            } else if (orders.getOrderType() == 2) {
                row.add("拼团订单");
            } else if (orders.getOrderType() == 3) {
                row.add("秒杀订单");
            } else if (orders.getOrderType() == 4) {
                row.add("积分订单");
            } else {
                row.add("未知");
            }
            row.add(orders.getOrderNum());
            row.add(StringUtils.isEmpty(orders.getConsignee()) ? "" : orders.getConsignee());
            row.add(StringUtils.isEmpty(orders.getMobile()) ? "" : orders.getMobile());
            row.add(StringUtils.isEmpty(orders.getDetail()) ? "" : orders.getDetail());
            row.add(orders.getPrice());
            row.add(orders.getPayMoney());
            row.add(orders.getCommissionPrice());
            row.add(StringUtils.isEmpty(orders.getRefund()) ? "" : orders.getRefund());
            row.add(StringUtils.isEmpty(orders.getRefusedRefund()) ? "" : orders.getRefusedRefund());
            //1app微信 2微信公众号 3微信小程序 4app支付宝 5H5支付宝 6零钱 7积分
            if (orders.getPayWay() == null) {
                row.add("未支付");
            } else if (orders.getPayWay() == 1) {
                row.add("app微信");
            } else if (orders.getPayWay() == 2) {
                row.add("微信公众号");
            } else if (orders.getPayWay() == 3) {
                row.add("微信小程序");
            } else if (orders.getPayWay() == 4) {
                row.add("app支付宝");
            } else if (orders.getPayWay() == 5) {
                row.add("H5支付宝");
            } else if (orders.getPayWay() == 6) {
                row.add("零钱");
            } else if (orders.getPayWay() == 7) {
                row.add("积分");
            } else {
                row.add("未知");
            }
            row.add(orders.getCreateAt());
            row.add(StringUtils.isEmpty(orders.getPayTime()) ? "" : orders.getPayTime());
            row.add(StringUtils.isEmpty(orders.getFinishTime()) ? "" : orders.getFinishTime());
            //1待付款 2已付款 3已发货 4已收货 5已取消 6退款中 7已退款 8拒绝退款 9拼团中 10已评价
            if (orders.getStatus() == 1) {
                row.add("待付款");
            } else if (orders.getStatus() == 2) {
                row.add("已付款");
            } else if (orders.getStatus() == 3) {
                row.add("已发货");
            } else if (orders.getStatus() == 4) {
                row.add("已收货");
            } else if (orders.getStatus() == 5) {
                row.add("已取消");
            } else if (orders.getStatus() == 6) {
                row.add("退款中");
            } else if (orders.getStatus() == 7) {
                row.add("已退款");
            } else if (orders.getStatus() == 8) {
                row.add("拒绝退款");
            } else if (orders.getStatus() == 9) {
                row.add("拼团中");
            } else if (orders.getStatus() == 10) {
                row.add("已评价");
            } else {
                row.add("未知");
            }
            rows.add(row);
        }
        data.setRows(rows);
        return data;
    }


    /**
     * 用户端订单列表
     *
     * @param page
     * @param size
     * @param userId
     * @param status
     * @return
     */
    @Override
    public Result findMyList(Integer page, Integer size, String userId, String status) {
        //根据时间排序
        Pageable pageable = PageRequest.of(page, size, Sort.by(new Sort.Order(Sort.Direction.DESC, "createAt")));
        // 构造自定义查询条件
        Specification<Orders> queryCondition = new Specification<Orders>() {
            @Override
            public Predicate toPredicate(Root<Orders> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();
                if (StringUtils.isNotEmpty(userId)) {
                    predicateList.add(criteriaBuilder.equal(root.get("userId"), userId));
                }
                if (!"0".equals(status)) {
                    predicateList.add(criteriaBuilder.equal(root.get("status"), status));
                }
                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
        Page<Orders> all = jpaRepository.findAll(queryCondition, pageable);
        List<SelfStore> allStore = selfStoreJpaRepository.findAll();
        //处理订单分销
        List<SelfOrderRelation> all1 = ordersRelationJpaRepository.findAll();
        //处理购物车订单bug
        List<Orders> cartList = new ArrayList<>();
        for (Orders o : all.getContent()) {
            List<SelfOrderRelation> relationList = new ArrayList<>();
            for (SelfOrderRelation r : all1) {
                if (o.getId().toString().equals(r.getOrderId().toString())) {
                    relationList.add(r);
                }
            }
            o.setRelationList(relationList);
            //处理购物车订单bug
            if (o.getIsCart() != null && o.getStatus() == 1) { //购物车的待付款订单
                cartList.add(o);
            }
        }
        this.cancel(cartList); //处理购物车订单bug
        return ResultUtil.success(all);
    }

    /**
     * 我的售后订单
     *
     * @param page
     * @param size
     * @param userId
     * @return
     */
    @Override
    public Result findMyRefundList(Integer page, Integer size, String userId) {
        //根据时间排序
        Pageable pageable = PageRequest.of(page, size, Sort.by(new Sort.Order(Sort.Direction.DESC, "createAt")));
        // 构造自定义查询条件
        Specification<Orders> queryCondition = new Specification<Orders>() {
            @Override
            public Predicate toPredicate(Root<Orders> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();
                if (StringUtils.isNotEmpty(userId)) {
                    predicateList.add(criteriaBuilder.equal(root.get("userId"), userId));
                }
                predicateList.add(criteriaBuilder.between(root.get("status"), 6, 8)); //6退款中 7已退款 8拒绝退款
                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
        return ResultUtil.success(jpaRepository.findAll(queryCondition, pageable));
    }

    /**
     * 生成订单编号
     *
     * @return
     */
    private String getGeneralOrder() {
        Date date = new Date();
        String newString = String.format("%0" + 4 + "d", (int) ((Math.random() * 9 + 1) * 1000));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = sdf.format(date);
        return format + newString;
    }

    /**
     * 保存订单：普通下单
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result saveBody(Orders entity) {
        reentrantReadWriteLock.writeLock().lock();
        try{

            log.info("订单下单，入参为:{}", JsonUtils.toJsonString(entity));

            Long userId = LoginUserHolder.getUserId();
            if(userId == null || userId <= 0) {
                return ResultUtil.error(-1, "用户未登录");
            }
            entity.setUserId(userId);

            if(entity.getOrderType()!=null && entity.getOrderType()!=5){
                //校验下单金额
                Result check = this.checkOrderInfo(entity);
                if (check.getStatus() != 0) {
                    return check;
                }
            }


        /*Goods goods = goodsJpaRepository.findById(entity.getGoodsId()).orElse(null);
        if(goods==null || !goods.getStatus().equals(1)){
            return ResultUtil.error(-200,"商品不存在或已下架，请刷新后重试！");
        }*/

        /*
        前端传入：用户id、收货人、手机号、详细地址、商品类型、商品标题、商品图片、商品描述、商品价格、商品个数、支付金额、
        后台生成：创建时间、订单号、订单状态
         */
            entity.setCreateAt(DateUtil.createTime()); //创建时间
            entity.setOrderNum(SeqUtils.dateSeq()); //订单号
            entity.setStatus(1); //订单状态（1待付款 2已付款 3已发货 4已收货 5已取消 6退款中 7已退款 8拒绝退款 9拼团中）
            if(entity.getIsExpress()!=null && entity.getIsExpress()==2){
                int size = goodsVirtualJpaRepository.findByGoodsId(entity.getGoodsId()).size();
                if(size<entity.getNumber()){
                    return ResultUtil.error(-1, entity.getTitle() + "库存不足");
                }
            }else{
                //判断库存
                Integer orderType = entity.getOrderType(); //订单类型
                if (orderType == 1) { //普通订单
                    if (!skuService.checkStock(entity.getSkuId(), entity.getNumber())) {
                        return ResultUtil.error(-1, entity.getTitle() + "库存不足");
                    }
                    skuService.lessStock(entity.getSkuId(), entity.getNumber()); //sku库存减少对应数量
                } else if (orderType == 2) { //拼团
                    if (!groupPinkService.checkPinkStock(entity.getSkuId(), entity.getNumber())) {
                        return ResultUtil.error(-1, entity.getTitle() + "库存不足");
                    }
                    groupSkuJpaRepository.lessPinkStock(entity.getSkuId(), entity.getNumber());
                } else if (orderType == 3) { //秒杀
                    if (!groupPinkService.checkSkillStock(entity.getSkuId(), entity.getNumber())) {
                        return ResultUtil.error(-1, entity.getTitle() + "库存不足");
                    }
                    groupSkuJpaRepository.lessSecKillStock(entity.getSkuId(), entity.getNumber());
                    int i = ordersRepository.checkBySecKillId(entity.getUserId(), entity.getSecKillId());
                    SelfSecKill selfSecKill = selfSeckillJpaRepository.findById(entity.getSecKillId()).orElse(null);
                    if(selfSecKill.getNumber()==null || i>=selfSecKill.getNumber()){
                        return ResultUtil.error(500,"当前商品已达到最大购买数量");
                    }
                }
            }

            //优惠券
            if (entity.getUserCouponsId() != null) {
                couponUserJpaRepository.usedCoupon(entity.getUserCouponsId());
            }
            // 非积分商品，记录一笔支付流水
            if(!"1".equals(entity.getPointFlag())) {
                PayRecord payRecord = payRecordService.savePayRecord(entity.getOrderNum(), entity.getPayMoney(), entity.getTitle(), PayScene.ORDER_PAY);
                entity.setPayNum(payRecord.getPaySeq()); //订单号
            }
            Orders save = jpaRepository.save(entity);
            savePartnerInfo(entity);
            return ResultUtil.success(save);
        }catch (Exception e){
            e.printStackTrace();
            if(e instanceof DescribeException) {
                throw e;
            }
            log.error("保存订单："+e.getMessage(),e);
            throw new DescribeException("系统繁忙，请稍后再试！", -200);
        }finally {
            reentrantReadWriteLock.writeLock().unlock();
        }
    }

    private void savePartnerInfo(Orders orders) {
        PartnerInfo partnerInfo = orders.getPartnerInfo();
        if((Long.valueOf(partnerTypeId).equals(orders.getType()) || Long.valueOf(instructorTypeId).equals(orders.getType())) && orders.getPartnerInfo() != null) {
            log.info("保存订单合伙人信息");
            OrderPartnerInfo orderPartnerInfo = new OrderPartnerInfo();
            BeanUtils.copyProperties(partnerInfo, orderPartnerInfo);
            orderPartnerInfo.setStatus("0");
            orderPartnerInfo.setOrderId(orders.getOrderNum());
            orderPartnerInfo.setUserId(orders.getUserId());
            orderPartnerInfo.setPartnerCode(orders.getGoodsId());
            orderPartnerInfo.setPartnerTitle(orders.getTitle());
            orderPartnerInfo.setCreateBy(String.valueOf(orders.getUserId()));
            orderPartnerInfo.setUpdateBy(String.valueOf(orders.getUserId()));
            orderPartnerInfo.setPrizes(JsonUtils.toJsonString(partnerInfo.getPrizeList()));
            orderPartnerInfo.setPrice(orders.getPrice());
            orderPartnerInfo.setPayMoney(orders.getPayMoney());
            orderPartnerInfoRepository.save(orderPartnerInfo);
        }
    }

    /**
     * 校验下单金额
     *
     * @param entity
     * @return
     */

    public Result checkOrderInfo(Orders entity) {
        if(entity.getGroupId()!=null){
            SelfGroup selfGroup = selfGroupJpaRepository.findById(entity.getGroupId()).orElse(null);
            if(selfGroup==null || selfGroup.getStatus()!=1){
                return ResultUtil.error(-1,"商品已被下架或移除，请选择其他商品！");
            }
        }else if(entity.getSecKillId()!=null){
            SelfSecKill selfSecKill = selfSeckillJpaRepository.findById(entity.getSecKillId()).orElse(null);
            if(selfSecKill==null || selfSecKill.getStatus()!=1){
                return ResultUtil.error(-1,"商品已被下架或移除，请选择其他商品！");
            }
        }else if(entity.getGoodsId()!=null){
            Goods g = goodsJpaRepository.findById(entity.getGoodsId()).orElse(null);
            if(g==null || g.getStatus()!=1){
                return ResultUtil.error(-1,"商品已被下架或移除，请选择其他商品！");
            }

            Long skuId = entity.getSkuId();
            SelfGoodsSku skuInfo = selfGoodsSkuJpaRepository.findById(skuId).orElse(null);
            AssertUtil.notNull(skuInfo, ExceptionEnum.GOODS_NOT_AVAILABLE);
            if(entity.getPrice().compareTo(skuInfo.getSkuPrice()) != 0) {
                return ResultUtil.error(-1,"商品信息有变动，请重新下单！");
            }
            entity.setTitle(g.getTitle());
            entity.setImg(skuInfo.getSkuImg());
            entity.setCommissionPrice(g.getCommissionPrice());
            entity.setPostagePrice(g.getPostagePrice());
            entity.setType(StringUtils.isEmpty(g.getTypeId()) ? 99999L : Long.valueOf(g.getTypeId()));
            entity.setPointFlag(g.getIsJiFenGoods() == null ? "0": String.valueOf(g.getIsJiFenGoods()));
            // 普通订单信息校验
            checkNormalOrder(entity, g);
        }
        //校验优惠券
        if (entity.getUserCouponsId() != null) {
            Goods g = goodsJpaRepository.findById(entity.getGoodsId()).orElse(null);
            if (!entity.getUserCouponsId().equals(g.getBrandId())) { //品牌id:前端传值有误，排除商品品牌id
                SelfCouponUser couponUser = couponUserJpaRepository.findById(entity.getUserCouponsId()).orElse(null);
                if (couponUser == null) {
                    return ResultUtil.error(-1, "优惠券不存在");
                }
                if (Double.parseDouble(couponUser.getLessMoney()) != entity.getCouponMoney().doubleValue()) {
                    return ResultUtil.error(-1, "优惠券金额有误");
                }
            }
        }
        //校验支付金额：商品金额：商品价格*个数+邮费=总价；支付金额：总价-优惠金额
        BigDecimal sumMoney = entity.getPrice().multiply(new BigDecimal(entity.getNumber()));
        if (entity.getPostagePrice() != null) { //邮费不为空
            sumMoney = sumMoney.add(entity.getPostagePrice());
        }
        BigDecimal payMoney = sumMoney;
        if (entity.getCouponMoney() != null) { //优惠券金额不为空
            payMoney = payMoney.subtract(entity.getCouponMoney());
        }
        // 合伙人，使用推广积分抵扣
        if(Long.valueOf(partnerTypeId).equals(entity.getType()) && entity.getDeductPoint() != null) {
            payMoney = payMoney.subtract(entity.getDeductPoint());
        }

        if (payMoney.compareTo(entity.getPayMoney()) != 0) {
            log.info("订单金额有误,下单金额:{}, 计算金额:{}", entity.getPayMoney(), payMoney);
            return ResultUtil.error(-1, "订单金额有误");
        }
        return ResultUtil.success();
    }

    /**
     * 普通订单校验
     * @param entity
     * @param goods
     */
    private void checkNormalOrder(Orders entity, Goods goods) {
        if(partnerTypeId.equals(goods.getTypeId()) || instructorTypeId.equals(goods.getTypeId())) {
            PartnerInfo partnerInfo = entity.getPartnerInfo();
            AssertUtil.assertTrue(entity.getNumber() == 1, ExceptionEnum.PARAM_ERROR, "每次只能下单一个商品");
            AssertUtil.notNull(partnerInfo, ExceptionEnum.PARAM_ERROR, "合伙人信息不能为空");
            AssertUtil.notEmpty(partnerInfo.getProvinceCode(), ExceptionEnum.PARAM_ERROR, "省份代码不能为空");
            AssertUtil.notEmpty(partnerInfo.getProvinceName(), ExceptionEnum.PARAM_ERROR, "省份不能为空");
            AssertUtil.notEmpty(partnerInfo.getCityCode(), ExceptionEnum.PARAM_ERROR, "城市代码不能为空");
            AssertUtil.notEmpty(partnerInfo.getCityName(), ExceptionEnum.PARAM_ERROR, "城市不能为空");
            AssertUtil.notEmpty(partnerInfo.getCountyCode(), ExceptionEnum.PARAM_ERROR, "区县代码不能为空");
            AssertUtil.notEmpty(partnerInfo.getCountyName(), ExceptionEnum.PARAM_ERROR, "区县不能为空");
            AssertUtil.notEmpty(partnerInfo.getAddressDetail(), ExceptionEnum.PARAM_ERROR, "小区不能为空");
            AssertUtil.notEmpty(partnerInfo.getUserName(), ExceptionEnum.PARAM_ERROR, "姓名不能为空");
            AssertUtil.notEmpty(partnerInfo.getTelephone(), ExceptionEnum.PARAM_ERROR, "联系电话不能为空");

            partnerInfo.setPartnerTypeId(entity.getType());
            if(instructorTypeId.equals(goods.getTypeId())) {
                partnerInfo.setPartnerUserId(LoginUserHolder.getUserId());
                AssertUtil.notEmpty(partnerInfo.getArmClasses(), ExceptionEnum.PARAM_ERROR, "兵种不能为空");
                AssertUtil.notEmpty(partnerInfo.getSpecialSkill(), ExceptionEnum.PARAM_ERROR, "特长不能为空");
                AssertUtil.notEmpty(partnerInfo.getServeDate(), ExceptionEnum.PARAM_ERROR, "服役时间不能为空");
                AssertUtil.notEmpty(partnerInfo.getRetirementDate(), ExceptionEnum.PARAM_ERROR, "退役时间不能为空");
                AssertUtil.notEmpty(partnerInfo.getPrizeList(), ExceptionEnum.PARAM_ERROR, "奖项列表不能为空");
                AssertUtil.assertTrue(partnerInfo.getPrizeList().size() >= 3, ExceptionEnum.PARAM_ERROR, "奖项输入不能少于3个");
            } else {
                if (entity.getDeductPoint() == null) {
                    entity.setDeductPoint(BigDecimal.ZERO);
                }
                checkAndSetPartnerOrderInfo(partnerInfo, entity);
            }
        }
    }

    /**
     * 校验并设置合伙人订单信息
     * @param partnerInfo
     * @param entity
     */
    private void checkAndSetPartnerOrderInfo(PartnerInfo partnerInfo, Orders entity) {
        // 判断是否是合伙人，只有合伙人才允许购买
        DeductPointRes deductPointRes = queryDeductPoint(entity.getGoodsId());
        AssertUtil.assertTrue(deductPointRes.getPartnerFlag(), ExceptionEnum.SPECIFY_USER_BUY);
        // 抵扣的积分跟计算出的抵扣积分是否一致
        AssertUtil.assertTrue(deductPointRes.getDeductPoint().compareTo(entity.getDeductPoint()) == 0, ExceptionEnum.DATA_CHANGED);
        // 查询购买的用户是否已注册
        UserInfo userByPhone = userService.getUserByPhone(partnerInfo.getTelephone());
        AssertUtil.notNull(userByPhone, ExceptionEnum.PHONE_NOT_EXISTS);
        // 存在待支付的主理人订单，则不允许下单
        List<OrderPartnerInfo> waitPayOrders = partnerService.queryWaitPayOrders(LoginUserHolder.getUserId(), Long.valueOf(partnerTypeId));
        AssertUtil.assertTrue(CollectionUtils.isEmpty(waitPayOrders), ExceptionEnum.WAIT_PAY_ORDER_EXISTS);

        partnerInfo.setPartnerUserId(userByPhone.getId());
        partnerInfo.setDeductPercent(deductPointRes.getDeductPercent());
        partnerInfo.setDeductPoint(deductPointRes.getDeductPoint());
        entity.setDeductPoint(deductPointRes.getDeductPoint());
    }
    /**
     * 购物车下单
     *
     * @param list
     * @return
     */
    @Override
    public Result saveAll(List<Orders> list) {
        //多订单时支付单号一致
        String payNum = this.getGeneralOrder();
        for (int i = 0; i < list.size(); i++) {
            Orders entity = list.get(i);
            //校验下单金额
            Result check = this.checkOrderInfo(entity);
            if (check.getStatus() != 0) {
                return check;
            }
            //判断库存
            Integer orderType = entity.getOrderType(); //订单类型
            if (!skuService.checkStock(entity.getSkuId(), entity.getNumber())) {
                return ResultUtil.error(-1, entity.getTitle() + "库存不足");
            }
            entity.setCreateAt(DateUtil.createTime()); //创建时间
            entity.setOrderNum(this.getGeneralOrder()); //订单号
            entity.setPayNum(payNum);
            entity.setStatus(1); //订单状态（1待付款 2已付款 3已发货 4已收货 5已取消 6退款中 7已退款 8拒绝退款 9拼团中）
            entity.setIsCart(1); //购物车订单 1
            Orders save = jpaRepository.saveAndFlush(entity);
            list.set(i, save);
            //sku库存减少对应数量
            skuService.lessStock(entity.getSkuId(), entity.getNumber());
            //优惠券
            if (entity.getUserCouponsId() != null) {
                couponUserJpaRepository.usedCoupon(entity.getUserCouponsId());
            }
        }
        return ResultUtil.success(list);
    }

    @Override
    public Result updateBody(Orders entity) {
        return ResultUtil.success(jpaRepository.save(entity));
    }

    @Override
    public Result findOne(Long id) {
        return ResultUtil.success(jpaRepository.findById(id).orElse(null));
    }

    @Override
    public Result delete(Long id) {
        jpaRepository.deleteById(id);
        return ResultUtil.success();
    }

    /**
     * 收入统计
     *
     * @param data
     * @param way
     * @return
     */
    @Override
    public Result income(String data, int way, Long storeId) {
        List<Orders> list = new ArrayList<>();
        if (storeId == null) {
            list = ordersRepository.findByStatus();
        } else {
            list = ordersRepository.findByStatusAndStoreId(storeId);
        }
        switch (way) {
            case 1:
                data = data.substring(0, 4);
                break; //年，截取前四个
            case 2:
                data = data.substring(0, 7);
                break; //月，前6
            default:
                break; //日，或者其他不做处理
        }
        BigDecimal sum0 = new BigDecimal("0.00"); //总收入
        BigDecimal sum1 = new BigDecimal("0.00"); //收入
        BigDecimal pay1 = new BigDecimal("0.00"); //微信
        BigDecimal pay2 = new BigDecimal("0.00"); //支付宝
        BigDecimal pay3 = new BigDecimal("0.00"); //余额
        int refundNum = 0;
        BigDecimal refundMoney = new BigDecimal("0.00"); //退款金额
        for (Orders o : list) {
            BigDecimal money = new BigDecimal("0.00");
            if (storeId == null) {
                money = o.getPayMoney() == null ? new BigDecimal("0.00") : o.getPayMoney(); //订单金额
            } else {
                money = o.getStoreMoney() == null ? new BigDecimal("0.00") : o.getStoreMoney(); //店铺金额
            }
            sum0 = sum0.add(money);
            if (StringUtils.isNotEmpty(o.getPayTime()) && o.getPayTime().contains(data)) {
                sum1 = sum1.add(money);
                switch (o.getPayWay()) { //根据支付方式细分：支付方式（1app微信 2微信公众号 3微信小程序 4app支付宝 5H5支付宝 6零钱）
                    case 1:
                        pay1 = pay1.add(money);
                        break;
                    case 2:
                        pay1 = pay1.add(money);
                        break;
                    case 3:
                        pay1 = pay1.add(money);
                        break;
                    case 4:
                        pay2 = pay2.add(money);
                        break;
                    case 5:
                        pay2 = pay2.add(money);
                        break;
                    case 6:
                        pay3 = pay3.add(money);
                        break;
                    case 8:
                        pay2 = pay2.add(money);
                        break;
                    default:
                        break;
                }
                if (o.getStatus().equals(7)) {
                    refundNum++;
                    refundMoney = refundMoney.add(money);
                }
            }

        }
        BigDecimal refundIncome = sum1.subtract(refundMoney);
        Map<String, Object> map = new HashMap<>();
        map.put("sum0", sum0);
        map.put("sum1", sum1);
        map.put("pay1", pay1);
        map.put("pay2", pay2);
        map.put("pay3", pay3);
        map.put("refundMoney", refundMoney);
        map.put("refundIncome", refundIncome);
        map.put("refundNum", refundNum);
        return ResultUtil.success(map);
    }

    /**
     * 订单成交量统计
     *
     * @param data
     * @return
     */
    @Override
    public Result statistical(String data, Long storeId) {
        List<Orders> list = new ArrayList<>();
        if (storeId == null) {
            list = ordersRepository.findByStatus();
        } else {
            list = ordersRepository.findByStatusAndStoreId(storeId);
        }
        int sum0 = 0; //年
        int sum1 = 0; //月
        int sum2 = 0; //日
        for (Orders o : list) {
            if (StringUtils.isNotEmpty(o.getPayTime()) && o.getPayTime().contains(data.substring(0, 4))) {
                String orderTime = o.getPayTime();
                if (orderTime.contains(data.substring(0, 4))) {
                    sum0++;
                }
                if (orderTime.contains(data.substring(0, 7))) {
                    sum1++;
                }
                if (orderTime.contains(data)) {
                    sum2++;
                }
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("sum0", sum0);
        map.put("sum1", sum1);
        map.put("sum2", sum2);
        return ResultUtil.success(map);
    }

    /**
     * 取消订单
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public Result orderCancel(Long id) {
        Orders orders = jpaRepository.findById(id).orElse(null);
        if (orders.getStatus() == 1) {
            orders.setStatus(5); //设置为已取消
            orders = jpaRepository.save(orders);
            //公众号消息：取消订单
            userService.orderCancel(orders.getUserId(), orders.getOrderNum(), DateUtil.createTime());
            //sku库存+1
            skuService.addStock(orders.getSkuId(), orders.getNumber());
            //优惠券
            if (orders.getUserCouponsId() != null) {
                couponUserJpaRepository.backCoupon(orders.getUserCouponsId());
            }
            // 合伙人，更新合伙人状态
            if(Long.valueOf(partnerTypeId).equals(orders.getType()) || Long.valueOf(instructorTypeId).equals(orders.getType())) {
                // 状态 0-待生效(待支付) 1-已生效 2-取消(未支付取消) 3-作废(如退款的情况)
                partnerService.updateStatus(orders.getOrderNum(), "2");
            }
            return ResultUtil.success(orders);
        } else {
            if(orders.getStatus() == 5) {
                log.info("当前订单已取消.");
                return ResultUtil.success(orders);
            }
            return ResultUtil.error(-1, "当前订单不可取消");
        }
    }

    /**
     * 发货
     *
     * @param id
     * @param expressName
     * @param expressNumber
     * @return
     */
    @Override
    public Result express(Long id, String expressName, String expressNumber) {
        Orders orders = jpaRepository.findById(id).orElse(null);
        orders.setExpressName(expressName);
        orders.setExpressNumber(expressNumber);
        orders.setStatus(3); //设置为已发货
        orders.setExpressTime(DateUtil.createTime());
        //公众号消息：发货提醒
        String address = orders.getConsignee() + "——" + orders.getMobile() + "——" + orders.getProvinces() + orders.getDetail(); //收货信息
        userService.orderExpress(orders.getUserId(), orders.getOrderNum(), DateUtil.createTime(), expressName, expressNumber, address);
        UserInfo userInfo = userRepository.getUserById(orders.getUserId());
        if (StringUtils.isNotEmpty(userInfo.getMpId())) {
            CommonInfo msgs2 = commonRepository.findOne(294);
            List<String> msgLists2 = new ArrayList<>();
            msgLists2.add(orders.getOrderNum());
            String title = orders.getTitle();
            if (title.length() > 15) {
                title = title.substring(0, 15) + "...";
            }
            msgLists2.add(title);
            msgLists2.add(expressName);
            msgLists2.add(expressNumber);
            String detail = orders.getDetail();
            if (detail.length() > 15) {
                detail = detail.substring(0, 15) + "...";
            }
            msgLists2.add(detail);
            AccountTokenServiceImpl.sendMsg(userInfo.getMpId(), msgs2.getValue(), msgLists2, 2);
        }
        return ResultUtil.success(jpaRepository.save(orders));
    }

    /**
     * 虚拟商品发货
     *
     * @param id
     * @return
     */
    @Override
    public Result expressVirtual(Long id) {
        Orders orders = jpaRepository.findById(id).orElse(null);
        if (orders.getIsExpress() != 2) { //是否需要发货(1需要发货 2无需发货)
            return ResultUtil.error(-1, "非虚拟商品,发货失败");
        }
        //虚拟商品发货，发货成功为确认收货，否则不做变化
        SelfGoodsVirtual v = this.sendExpress(orders);
        if (v != null) {
            orders.setVirtualId(v.getId()); //虚拟商品id
            orders.setExpressTime(DateUtil.createTime()); //发货时间
            orders.setFinishTime(DateUtil.createTime()); //收货时间
            orders.setStatus(4); //确认收货
            Orders save = jpaRepository.save(orders);
            //商品销量增加
            goodsService.salesAdd(orders.getGoodsId(), orders.getNumber());
            if(orders.getSkuId()!=null){
                skuService.addSales(orders.getSkuId(), orders.getNumber());
            }
            if (orders.getStoreId() != null){
                //商户销量增加
                selfStoreService.salesAdd(orders.getStoreId(), orders.getNumber());
                //商户余额增加
                SelfMerchantApply m = selfMerchantApplyJpaRepository.findById(orders.getMerchantId()).orElse(null);
                if(m.getMoney()==null){
                    m.setMoney(BigDecimal.ZERO);
                }
                SelfStore selfStore = selfStoreJpaRepository.findById(orders.getStoreId()).orElse(null);
                BigDecimal pingMoney = selfStore.getRate().multiply(orders.getStoreMoney());
                BigDecimal storeMoney=orders.getStoreMoney().subtract(pingMoney);
                storeMoney=storeMoney.setScale(2,BigDecimal.ROUND_HALF_DOWN);
                selfMerchantApplyJpaRepository.updateMoneyAdd(m.getMoney().add(storeMoney), orders.getMerchantId());
                iMoneyDetailsService.saveMerchant(m.getId(),1,1,"订单到账："+orders.getOrderNum(),"到账金额："+storeMoney,storeMoney.doubleValue());

            }
            return ResultUtil.success(save);
        } else {
            return ResultUtil.error(-1, "虚拟商品库存不足：" + orders.getTitle());
        }
    }

    /**
     * 确认收货
     *
     * @param id
     * @return
     */
    @Override
    public Result orderConfirm(Long id) {
        //1.订单设置已收货
        Orders orders = jpaRepository.findById(id).orElse(null);
        orders.setStatus(4); //4已收货
        orders.setFinishTime(DateUtil.createTime()); //设置完成时间
        //商品销量增加
        goodsService.salesAdd(orders.getGoodsId(), orders.getNumber());
        //sku销量增加
        skuService.addSales(orders.getSkuId(), orders.getNumber());
        //积分商品确认收货
        if (orders.getOrderType() == 4) {
            return ResultUtil.success(jpaRepository.save(orders));
        }
        //2.订单分销
        List<SelfOrderRelation> list = ordersRelationService.findByOrdersId(id); //订单关联的分销列表
        for (SelfOrderRelation s : list) {
            //设置收货时间、收货七天后存入用户零钱
            s.setFinishTime(DateUtil.createTime());
            ordersRelationService.updateBody(s);
        }
        //6.用户积分添加
        String jifenCount = orders.getPayMoney().toString();
        Long userId = orders.getUserId();
        userRepository.addOrderJifen(jifenCount, userId);
        //7.用户积分明细
        JiFen jiFen = new JiFen();
        jiFen.setCreateAt(DateUtil.createTime());
        jiFen.setNumber(jifenCount);
        jiFen.setUserId(userId.toString());
        jiFen.setContent("自营商城");
        jiFen.setDes("自营商城积分+" + jifenCount);
        jiFenService.saveBody(jiFen);

        if (orders.getStoreId() != null) {
            //商户销量增加
            selfStoreService.salesAdd(orders.getStoreId(), orders.getNumber());
            if(orders.getMerchantId()!=null){
                //商户余额增加
                SelfMerchantApply m = selfMerchantApplyJpaRepository.findById(orders.getMerchantId()).orElse(null);
                if (m.getMoney() == null) {
                    m.setMoney(BigDecimal.ZERO);
                }
                SelfStore selfStore = selfStoreJpaRepository.findById(orders.getStoreId()).orElse(null);
                BigDecimal pingMoney = selfStore.getRate().multiply(orders.getStoreMoney());
                BigDecimal storeMoney=orders.getStoreMoney().subtract(pingMoney);
                storeMoney=storeMoney.setScale(2,BigDecimal.ROUND_HALF_DOWN);
                selfMerchantApplyJpaRepository.updateMoneyAdd(m.getMoney().add(storeMoney), orders.getMerchantId());
                iMoneyDetailsService.saveMerchant(m.getId(),1,1,"订单到账："+orders.getOrderNum(),"到账金额："+storeMoney,storeMoney.doubleValue());

            }

        }
        return ResultUtil.success(jpaRepository.save(orders));
    }

    /**
     * 检测支付
     *
     * @param id
     * @return
     */
    @Override
    public Result checkPay(Long id) {
        Orders one = jpaRepository.findById(id).orElse(null);
        if (one.getStatus() == 2) {
            return ResultUtil.success(one);
        }
        return ResultUtil.error(-1, "未支付");
    }

    @Override
    public Orders findByOrderNum(String orderNum) {
        return jpaRepository.findByOrderNum(orderNum);
    }

    @Override
    public List<Orders> findByPayNum(String payNum) {
        return jpaRepository.findByPayNum(payNum);
    }

    /**
     * 零钱支付
     *
     * @param id 订单id
     * @return
     */
    @Override
    public Result changePay(String id) {
        reentrantReadWriteLock.writeLock().lock();
        try {
            String[] ids = id.split(",");
            for (String s : ids) {
                //1.获取订单、用户信息
                Orders orders = jpaRepository.findById(Long.valueOf(s)).orElse(null);
                if(orders.getStatus()!=1){
                    return ResultUtil.error(-200,"订单已经支付过了！");
                }
                if (orders.getGroupPinkId() != null) {
                    SelfGroupPink selfGroupPink = selfGroupPinkJpaRepository.findById(orders.getGroupPinkId()).orElse(null);
                    if (selfGroupPink.getStatus() == 2) {
                        return ResultUtil.error(-200, "拼团已完成，无法参与！");
                    }
                }
                if(orders.getGroupId()!=null){
                    SelfGroup selfGroup = selfGroupJpaRepository.findById(orders.getGroupId()).orElse(null);
                    if(selfGroup==null || selfGroup.getStatus()!=1){
                        return ResultUtil.error(-1,"商品已被下架或移除，请选择其他商品！");
                    }
                }else if(orders.getSecKillId()!=null){
                    SelfSecKill selfSecKill = selfSeckillJpaRepository.findById(orders.getSecKillId()).orElse(null);
                    if(selfSecKill==null || selfSecKill.getStatus()!=1){
                        return ResultUtil.error(-1,"商品已被下架或移除，请选择其他商品！");
                    }
                }else{
                    Goods g = goodsJpaRepository.findById(orders.getGoodsId()).orElse(null);
                    if(g==null || g.getStatus()!=1){
                        return ResultUtil.error(-1,"商品已被下架或移除，请选择其他商品！");
                    }
                }
                UserInfo user = userJpaRepository.findById(orders.getUserId()).orElse(null);
                double payMoney = orders.getPayMoney().doubleValue();
                double money = new BigDecimal(user.getJifen()).doubleValue();
                if (payMoney > money) {
                    return ResultUtil.error(-1, "零钱余额不足");
                }
                //2.用户零钱减少
                userRepository.updateJiFenDelete(orders.getPayMoney().toString(), user.getId());
                //3.零钱减少明细
                MoneyDetails moneyDetails = new MoneyDetails();
                moneyDetails.setClassify(1);
                moneyDetails.setUserId(user.getId());
                moneyDetails.setType(2); //减少
                moneyDetails.setTitle("自营商城付款，订单号：" + orders.getOrderNum());
                moneyDetails.setContent(orders.getTitle());
                moneyDetails.setMoney(orders.getPayMoney().doubleValue());
                moneyDetails.setCreateTime(DateUtil.createTime());
                moneyDetailsJpaRepository.save(moneyDetails);

                SelfOrderRemind r = new SelfOrderRemind();
                r.setOrdersId(orders.getId());
                r.setCreateTime(DateUtil.createTime());
                r.setStatus(1);
                r.setType(1);
                if (orders.getMerchantId() != null) {
                    r.setMerchantId(orders.getMerchantId());
                }
                selfOrdersRemindJpaRepository.save(r);


                //订单分销
                this.fenXiao(orders.getId());
                //4.支付成功处理订单
                orders.setPayWay(6); //支付方式（1app微信 2微信公众号 3微信小程序 4app支付宝 5H5支付宝 6零钱）
                orders.setPayTime(DateUtil.createTime()); //设置支付时间
                orders.setStatus(2); //订单状态（1待付款 2已付款 3已发货 4已收货 5已取消 6退款中 7已退款 8拒绝退款 9拼团中）
                //虚拟商品处理
                if (orders.getOrderType() == 1) { //普通订单
                    if (orders.getIsExpress() == 2) { //是否需要发货(1需要发货 2无需发货)
                        //虚拟商品发货，发货成功为确认收货，否则不做变化
                        SelfGoodsVirtual v = this.sendExpress(orders);
                        if (v != null) {
                            orders.setVirtualId(v.getId()); //虚拟商品id
                            orders.setExpressTime(DateUtil.createTime()); //发货时间
                            orders.setStatus(4); //确认收货
                            //商品销量增加
                            goodsService.salesAdd(orders.getGoodsId(), orders.getNumber());
                            if(orders.getSkuId()!=null){
                                skuService.addSales(orders.getSkuId(), orders.getNumber());
                            }
                            if (orders.getStoreId() != null){
                                //商户销量增加
                                selfStoreService.salesAdd(orders.getStoreId(), orders.getNumber());
                                //商户余额增加
                                SelfMerchantApply m = selfMerchantApplyJpaRepository.findById(orders.getMerchantId()).orElse(null);
                                if(m.getMoney()==null){
                                    m.setMoney(BigDecimal.ZERO);
                                }
                                SelfStore selfStore = selfStoreJpaRepository.findById(orders.getStoreId()).orElse(null);
                                BigDecimal pingMoney = selfStore.getRate().multiply(orders.getStoreMoney());
                                BigDecimal storeMoney=orders.getStoreMoney().subtract(pingMoney);
                                storeMoney=storeMoney.setScale(2,BigDecimal.ROUND_HALF_DOWN);
                                selfMerchantApplyJpaRepository.updateMoneyAdd(m.getMoney().add(storeMoney), orders.getMerchantId());
                                iMoneyDetailsService.saveMerchant(m.getId(),1,1,"订单到账："+orders.getOrderNum(),"到账金额："+storeMoney,storeMoney.doubleValue());

                            }
                        }
                    } else if (orders.getIsExpress() == 3) { //核销订单
                        orders.setStatus(3); //待收货、待使用
                    }
                } else if (orders.getOrderType() == 2) {
                    orders.setStatus(9);
                    //拼团业务处理
                    this.pink(orders);
                }
                this.updateBody(orders);


                //公众号消息通知
                userService.orderPay(orders.getUserId(), orders.getOrderNum(), orders.getPayMoney().toString(), orders.getCreateAt());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("零钱支付异常：" + e.getMessage(), e);
        } finally {
            reentrantReadWriteLock.writeLock().unlock();
        }


        return ResultUtil.success();
    }

    /**
     * 积分支付
     *
     * @param id
     * @return
     */
    @Override
    public Result jiFenPay(String id) {
        //1.获取订单、用户信息
        Orders orders = jpaRepository.findById(Long.valueOf(id)).orElse(null);
        UserInfo user = userJpaRepository.findById(orders.getUserId()).orElse(null);
        double payMoney = orders.getPayMoney().doubleValue();
        double money = Double.parseDouble(user.getOrderJifen());
        if (payMoney > money) {
            return ResultUtil.error(-1, "积分不足");
        }
        //2.用户积分减少
        userRepository.lessOrderJifen(orders.getPayMoney().toString(), user.getId());
        //3.积分减少明细
        JiFen jiFen = new JiFen();
        jiFen.setCreateAt(DateUtil.createTime());
        jiFen.setNumber(orders.getPayMoney().toString());
        jiFen.setUserId(String.valueOf(user.getId()));
        jiFen.setContent("积分兑换");
        jiFen.setDes("积分兑换:【" + orders.getTitle() + "】-" + payMoney);
        jiFenService.saveBody(jiFen);
        //4.支付成功处理订单
        orders.setPayWay(7); //支付方式（1app微信 2微信公众号 3微信小程序 4app支付宝 5H5支付宝 6零钱 7积分）
        orders.setPayTime(DateUtil.createTime()); //设置支付时间
        orders.setStatus(2); //订单状态（1待付款 2已付款 3已发货 4已收货 5已取消 6退款中 7已退款 8拒绝退款 9拼团中）
        //虚拟商品处理
        if (orders.getIsExpress() == 2) { //是否需要发货(1需要发货 2无需发货 3核销订单)
            //虚拟商品发货，发货成功为确认收货，否则不做变化
            SelfGoodsVirtual v = this.sendExpress(orders);
            if (v != null) {
                orders.setVirtualId(v.getId()); //虚拟商品id
                orders.setExpressTime(DateUtil.createTime()); //发货时间
                orders.setStatus(4); //确认收货
            }
        } else if (orders.getIsExpress() == 3) { //核销订单
            orders.setStatus(3); //待收货、待使用
        }
        this.updateBody(orders); //保存订单
        //公众号消息通知
        userService.orderPay(orders.getUserId(), orders.getOrderNum(), orders.getPayMoney().toString(), orders.getCreateAt());
        return ResultUtil.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pointPay(PointPayReq req) {
        UserInfo userInfo = LoginUserHolder.getUserInfo();
        AssertUtil.assertTrue(userInfo != null && userInfo.getId() > 0, ExceptionEnum.WRONT_TOKEN);

        Orders orders = jpaRepository.findById(req.getOrderId()).orElse(null);
        AssertUtil.assertTrue(orders != null, ExceptionEnum.ORDER_NOF);
        AssertUtil.assertTrue(orders.getUserId().equals(userInfo.getId()), ExceptionEnum.ORDER_NOT_MATCH);
        AssertUtil.assertTrue("1".equals(orders.getPointFlag()), ExceptionEnum.NOT_POINT_ORDER);
        // 判断积分是否足够
        AssertUtil.assertTrue(userInfo.getPointAvailable().compareTo(orders.getPayMoney()) >= 0, ExceptionEnum.POINT_NOT_ENOUGH);
        // 记录一笔积分流水
        insertRecord(userInfo.getId(), "USE", PointScene.USE_BUY, orders.getPayMoney(), orders);
        userRepository.subPoint(orders.getPayMoney(), userInfo.getId());
        // 更新订单状态
        orders.setPayWay(7); //支付方式（1app微信 2微信公众号 3微信小程序 4app支付宝 5H5支付宝 6零钱 7积分）
        orders.setPayTime(DateUtil.createTime()); //设置支付时间
        orders.setStatus(2); //订单状态（1待付款 2已付款 3已发货 4已收货 5已取消 6退款中 7已退款 8拒绝退款 9拼团中）
        //虚拟商品处理
        if (orders.getIsExpress() == 2) { //是否需要发货(1需要发货 2无需发货 3核销订单)
            //虚拟商品发货，发货成功为确认收货，否则不做变化
            SelfGoodsVirtual v = this.sendExpress(orders);
            if (v != null) {
                orders.setVirtualId(v.getId()); //虚拟商品id
                orders.setExpressTime(DateUtil.createTime()); //发货时间
                orders.setStatus(4); //确认收货
            }
        } else if (orders.getIsExpress() == 3) { //核销订单
            orders.setStatus(3); //待收货、待使用
        }
        this.updateBody(orders); //保存订单
    }

    private PointRecord insertRecord(Long userId, String type, PointScene scene, BigDecimal point, Orders orders) {
        return insertRecord(userId, type, scene, point, orders, null, null);
    }

    private PointRecord insertRecord(Long userId, String type, PointScene scene, BigDecimal point, Orders orders, Long subUserId, String subUserPhone) {
        String seq = SeqTools.dateSeq();
        PointRecord record = new PointRecord();
        record.setSeqNo(seq);
        record.setRecordType(type);
        record.setPointAmount(point);
        record.setUserId(userId);
        record.setSceneCode(scene.getCode());
        record.setSubUserId(subUserId);
        record.setSubUserPhone(subUserPhone);

        record.setBusinessId(orders.getOrderNum());
        record.setItemId(String.valueOf(orders.getGoodsId()));
        record.setItemName(orders.getTitle());

        record.setCreateBy(String.valueOf(orders.getUserId()));
        record.setUpdateBy(String.valueOf(orders.getUserId()));

        pointRecordRepository.save(record);
        log.info("插入积分记录表记录: {}", JsonUtils.toJsonString(record));
        return record;
    }

    //处理虚拟商品
    @Override
    public SelfGoodsVirtual sendExpress(Orders orders) {
        //发送虚拟商品
        SelfGoodsVirtual v = selfGoodsVirtualService.sendGoods(orders.getGoodsId());
        if (v != null) { //有商品
            //订单消息
            MessageInfo messageInfo = new MessageInfo();
            messageInfo.setState("4");
            messageInfo.setTitle("订单支付成功");
            messageInfo.setContent("您购买的商品【" + orders.getTitle() + "】。请前往： " + v.getLinkUrl() + "中领取兑换，兑换码如下：" + v.getContent());
            messageInfo.setUserId(orders.getUserId().toString());
            iMessageService.saveBody(messageInfo);
            return v;
        } else { //无商品时,后台管理发送发货提醒
            SelfOrderRemind r = new SelfOrderRemind();
            r.setOrdersId(orders.getId());
            r.setCreateTime(DateUtil.createTime());
            r.setStatus(1);
            r.setType(1);
            if (orders.getMerchantId() != null) {
                r.setMerchantId(orders.getMerchantId());
            }
            selfOrdersRemindJpaRepository.save(r);
            return null;
        }
    }

    /**
     * 拼团订单处理
     */
    @Override
    public void pink(Orders orders) {
        //拼团业务处理
        if (orders.getOrderType() == 2) {
            //发起拼团
            if (orders.getGroupPinkId() == null) {
                groupPinkService.createPink(orders);
            } else {
                groupPinkService.joinPink(orders);
            }
        }
    }

    /**
     * 发起退款
     *
     * @param id
     * @param refund
     * @return
     */
    @Override
    public Result refund(Long id, String refund) {
        Orders orders = jpaRepository.findById(id).orElse(null);
        orders.setRefund(refund);
        orders.setStatus(6); //6退款中
        if (orders.getOrderType() == 5) {
            //保证金退款发起时间
            selfMarginJpaRepository.refundStartMargin(orders.getId(), DateUtil.createTime());
        }
        return ResultUtil.success(jpaRepository.save(orders));
    }

    /**
     * 确认退款
     *
     * @param id
     * @return
     */
    @Override
    public Result refundMoney(Long id) {
        boolean refund = true;
        //1.获取订单
        Orders orders = jpaRepository.findById(id).orElse(null);
        Integer payWay = orders.getPayWay();
        UserInfo user = userJpaRepository.findById(orders.getUserId()).orElse(null);
        //2.零钱支付退款
        if (payWay == 6) { //支付方式（1app微信 2微信公众号 3微信小程序 4app支付宝 5H5支付宝 6零钱）
            //2.1用户信息

            //2.2用户零钱增加
            userRepository.updateJiFenAdd(orders.getPayMoney().toString(), user.getId());
            //2.3零钱增加明细
            MoneyDetails moneyDetails = new MoneyDetails();
            moneyDetails.setClassify(1);
            moneyDetails.setUserId(user.getId());
            moneyDetails.setType(1); //增加
            moneyDetails.setTitle("自营商城退款，订单号：" + orders.getOrderNum());
            moneyDetails.setContent(orders.getTitle());
            moneyDetails.setMoney(orders.getPayMoney().doubleValue());
            moneyDetails.setCreateTime(DateUtil.createTime());
            moneyDetailsJpaRepository.save(moneyDetails);
        } else if (payWay == 4 || payWay == 5 || payWay == 8) { //支付方式（1app微信 2微信公众号 3微信小程序 4app支付宝 5H5支付宝 6零钱 7积分 8支付宝网站）
            //3.支付宝退款
            refund = selfAliPayService.refund(id);
        } else if (payWay == 1 || payWay == 2 || payWay == 3) {
            //4.微信退款
            refund = selfWXService.refund(id);
        } else {
            return ResultUtil.error(-1, "支付方式有误");
        }
        //5.删除分销订单
        List<SelfOrderRelation> list = ordersRelationService.findByOrdersId(id); //订单关联的分销列表
        for (SelfOrderRelation s : list) {
            ordersRelationService.delete(s.getId());
        }
        //6.处理订单已退款
        if (refund) {
            orders.setStatus(7); //已退款
            jpaRepository.save(orders);
            skuService.addStock(orders.getSkuId(), orders.getNumber());
            //店铺保证金退款
            if (orders.getOrderType() == 5) { //保证金订单
                selfMarginService.refundMargin(orders.getId());
            } else { //用户订单
                //公众号消息：退款
                userService.orderRefund(orders.getUserId(), orders.getPayMoney().toString());
            }

            // 合伙人，更新合伙人状态
            if(Long.valueOf(partnerTypeId).equals(orders.getType())) {
                // 状态 0-待生效(待支付) 1-已生效 2-取消(未支付取消) 3-作废(如退款的情况)
                partnerService.updateStatus(orders.getOrderNum(), "2");
            }

            if (StringUtils.isNotEmpty(user.getMpId())) {
                CommonInfo msgs2 = commonRepository.findOne(294);
                List<String> msgLists2 = new ArrayList<>();
                msgLists2.add(orders.getOrderNum());
                String title = orders.getTitle();
                if (title.length() > 15) {
                    title = title.substring(0, 15) + "...";
                }
                msgLists2.add(title);
                msgLists2.add(String.valueOf(orders.getPayMoney()));
                AccountTokenServiceImpl.sendMsg(user.getMpId(), msgs2.getValue(), msgLists2, 1);
            }

            return ResultUtil.success();
        } else {
            return ResultUtil.error(-1, "退款失败");
        }
    }

    /**
     * 拒绝退款
     *
     * @param ordersId
     * @param refusedRefund
     * @return
     */
    @Override
    public Result refusedRefund(Long ordersId, String refusedRefund) {
        Orders order = jpaRepository.findById(ordersId).orElse(null);
        //拒绝退款回到待发货状态
        order.setStatus(2); //订单状态（1待付款 2已付款 3已发货 4已收货 5已取消 6退款中 7已退款 8拒绝退款 9拼团中 10已评价）
        order.setRefusedRefund(refusedRefund);
        order = jpaRepository.save(order);
        //订单消息
        MessageInfo messageInfo = new MessageInfo();
        messageInfo.setState("4");
        messageInfo.setTitle("退款失败通知");
        messageInfo.setContent("您发起的退款申请退款失败，订单编号：" + order.getOrderNum() + "退款失败原因：" + refusedRefund);
        messageInfo.setUserId(order.getUserId().toString());
        iMessageService.saveBody(messageInfo);
        return ResultUtil.success(order);
    }

    /**
     * 订单分销处理
     */
    @Override
    public void fenXiao(Long ordersId) {
        //1.查询订单
        Orders o = jpaRepository.getOne(ordersId);
        BigDecimal commissionPrice = o.getCommissionPrice(); //订单的佣金
        //2.查询订单用户
        UserInfo u = userJpaRepository.getOne(o.getUserId());
        BigDecimal grade = new BigDecimal(u.getGrade()); //用户佣金等级
        //BigDecimal sum = commissionPrice.multiply(grade); //计算可以分配佣金
        BigDecimal sum = commissionPrice; //计算可以分配佣金
        //分销金额不能0
        if (sum == null || sum.doubleValue() < 0.01) {
            return;
        }
        //3.判断是否是会员
        if (StringUtils.isNotEmpty(u.getRelationId())) { //用户是会员
            //4.判断有无上级
            String invitation = u.getInvitation();
            if (StringUtils.isNotEmpty(invitation)) { //用户有上级
                UserInfo shangJiUser = userRepository.getUserByRelationId(invitation);
                //5.计算上级分配佣金
                CommonInfo one = commonRepository.findOne(91); // 佣金等级 1  二级佣金  2  三级佣金
                String value = commonRepository.findOne(43).getValue(); //上级佣金比例
                BigDecimal shangJiMoney = sum.multiply(new BigDecimal(value));
                //6.计算用户分配的佣金
                BigDecimal selfMoney = sum.subtract(shangJiMoney);
                //区分是二级佣金还是三级佣金  1  二级佣金  2  三级佣金
                if ("1".equals(one.getValue())) {
                    //7.保存团长的佣金明细
                    /*
                    相同部分：订单id、状态1未到账、订单实付金额、商品id、商品照片、商品标题
                    区分上下级：用户id、用户手机号、订单佣金、分销明细、来源（1下级 2自己）、下级用户id、下级用户名称
                     */
                    SelfOrderRelation s = new SelfOrderRelation();
                    s.setOrderId(o.getId());
                    s.setStatus(1);
                    s.setPayMoney(o.getPayMoney());
                    s.setGoodsId(o.getGoodsId());
                    s.setGoodsImg(o.getImg());
                    s.setGoodsTitle(o.getTitle());
                    //不同部分：佣金不同、代理佣金、团队
                    s.setUserId(shangJiUser.getId()); //团长id
                    s.setUserName(shangJiUser.getNickName()); //团长姓名
                    s.setPhone(shangJiUser.getPhone()); //团长手机号
                    s.setCommissionPrice(shangJiMoney); //佣金不同
                    s.setCommissionMoney(selfMoney); //代理佣金
                    s.setDetail("【直属购买】" + o.getTitle());
                    s.setMoneyFrom(1); //团队
                    s.setLowerUserId(u.getId());
                    s.setLowerUserName(u.getNickName());
                    ordersRelationService.saveBody(s);
                    //8.保存代理的佣金明细
                    SelfOrderRelation s1 = new SelfOrderRelation();
                    s1.setOrderId(o.getId());
                    s1.setStatus(1);
                    s1.setPayMoney(o.getPayMoney());
                    s1.setGoodsId(o.getGoodsId());
                    s1.setGoodsImg(o.getImg());
                    s1.setGoodsTitle(o.getTitle());
                    s1.setUserId(u.getId()); //用户id
                    s1.setUserName(u.getNickName()); //用户姓名
                    s1.setPhone(u.getPhone()); //用户手机号
                    s1.setCommissionPrice(selfMoney); //佣金不同
                    s1.setCommissionMoney(shangJiMoney); //团长佣金
                    s1.setDetail("【自己购买】" + o.getTitle());
                    s1.setMoneyFrom(2); //自己
                    ordersRelationService.saveBody(s1);
                } else {
                    //非直属佣金抽成
                    CommonInfo one1 = commonRepository.findOne(92);
                    BigDecimal feiMoney = sum.multiply(new BigDecimal(one1.getValue()));
                    //6.计算用户分配的佣金
                    //selfMoney = AmountCalUtils.sub(selfMoney, feiMoney);
                    selfMoney = selfMoney.subtract(feiMoney);
                    //7.保存团长的佣金明细
                    /*
                    相同部分：订单id、状态1未到账、订单实付金额、商品id、商品照片、商品标题
                    区分上下级：用户id、用户手机号、订单佣金、分销明细、来源（1下级 2自己）、下级用户id、下级用户名称
                     */
                    SelfOrderRelation s = new SelfOrderRelation();
                    s.setOrderId(o.getId());
                    s.setStatus(1);
                    s.setPayMoney(o.getPayMoney());
                    s.setGoodsId(o.getGoodsId());
                    s.setGoodsImg(o.getImg());
                    s.setGoodsTitle(o.getTitle());
                    //不同部分：佣金不同、代理佣金、团队
                    s.setUserId(shangJiUser.getId()); //团长id
                    s.setUserName(shangJiUser.getNickName()); //团长姓名
                    s.setPhone(shangJiUser.getPhone()); //团长手机号
                    s.setCommissionPrice(shangJiMoney); //佣金不同
                    s.setCommissionMoney(selfMoney); //代理佣金
                    s.setDetail("【直属购买】" + o.getTitle());
                    s.setMoneyFrom(1); //直属
                    s.setLowerUserId(u.getId());
                    s.setLowerUserName(u.getNickName());
                    ordersRelationService.saveBody(s);
                    //8.保存代理的佣金明细
                    SelfOrderRelation s1 = new SelfOrderRelation();
                    s1.setOrderId(o.getId());
                    s1.setStatus(1);
                    s1.setPayMoney(o.getPayMoney());
                    s1.setGoodsId(o.getGoodsId());
                    s1.setGoodsImg(o.getImg());
                    s1.setGoodsTitle(o.getTitle());
                    s1.setUserId(u.getId()); //用户id
                    s1.setUserName(u.getNickName()); //团长姓名
                    s1.setPhone(u.getPhone()); //用户手机号
                    s1.setCommissionPrice(selfMoney); //佣金不同
                    s1.setCommissionMoney(shangJiMoney); //团长佣金
                    s1.setDetail("【自己购买】" + o.getTitle());
                    s1.setMoneyFrom(2); //自己
                    ordersRelationService.saveBody(s1);
                    //非直属佣金
                    UserInfo feiUser = userRepository.getUserByRelationId(shangJiUser.getInvitation());
                    if (feiUser != null) {
                        SelfOrderRelation s2 = new SelfOrderRelation();
                        s2.setOrderId(o.getId());
                        s2.setStatus(1);
                        s2.setPayMoney(o.getPayMoney());
                        s2.setGoodsId(o.getGoodsId());
                        s2.setGoodsImg(o.getImg());
                        s2.setGoodsTitle(o.getTitle());
                        s2.setUserId(feiUser.getId()); //团长id
                        s2.setUserName(feiUser.getNickName()); //团长姓名
                        s2.setPhone(feiUser.getPhone()); //团长手机号
                        s2.setCommissionPrice(feiMoney); //佣金不同
                        s2.setCommissionMoney(selfMoney); //代理佣金
                        s2.setDetail("【非直属购买】" + o.getTitle());
                        s2.setMoneyFrom(3); //非直属
                        s2.setLowerUserId(u.getId());
                        s2.setLowerUserName(u.getNickName());
                        ordersRelationService.saveBody(s2);
                    }
                }
            }
        }
    }


    @Override
    public Result pendingOrder() {
        return ResultUtil.success(ordersRepository.pendingOrder());
    }

    @Override
    public Result remind(Long ordersId) {
        SelfOrderRemind remind = selfOrdersRemindJpaRepository.findByOrdersId(ordersId);
        Orders orders = jpaRepository.findById(ordersId).orElse(null);
        if (remind != null) {
            if (remind.getStatus() == 1) {
                return ResultUtil.error(0, "已经提醒发货");
            } else {
                remind.setStatus(1);
                remind.setType(1);
                selfOrdersRemindJpaRepository.save(remind);
            }
        } else {
            SelfOrderRemind r = new SelfOrderRemind();
            r.setOrdersId(ordersId);
            r.setCreateTime(DateUtil.createTime());
            r.setStatus(1);
            r.setType(1);
            if (orders.getMerchantId() != null) {
                r.setMerchantId(orders.getMerchantId());
            }
            selfOrdersRemindJpaRepository.save(r);
        }
        return ResultUtil.success();
    }

    @Override
    public Result remindOrder(Long merchantId) {
        // 构造自定义查询条件
        Specification<SelfOrderRemind> queryCondition = new Specification<SelfOrderRemind>() {
            @Override
            public Predicate toPredicate(Root<SelfOrderRemind> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();
                predicateList.add(criteriaBuilder.equal(root.get("status"), 1));
                if (merchantId != null) {
                    predicateList.add(criteriaBuilder.equal(root.get("merchantId"), merchantId));
                } else {
                    predicateList.add(criteriaBuilder.isNull(root.get("merchantId")));
                }
                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
        Map<String, Object> map = new HashMap<>();
        int sum0 = 0; //1发货消息
        int sum1 = 0; //2投诉消息
        List<SelfOrderRemind> all = selfOrdersRemindJpaRepository.findAll(queryCondition);
        for (SelfOrderRemind r : all) {
            switch (r.getType()) {
                case 1:
                    sum0++;
                    break;
                case 2:
                    sum1++;
                    break;
            }
            r.setStatus(2);
        }
        selfOrdersRemindJpaRepository.saveAll(all);
        map.put("sum0", sum0);
        map.put("sum1", sum1);
        return ResultUtil.success(map);
    }

    @Override
    public Result payCount(Long userId) {
        Map<String, Object> map = new HashMap<>();
        //今日付款数量
        String date = DateUtil.createDate(); //今日
        int count1 = ordersRepository.todayPayCount(userId, date);
        //本月付款数量
        String month = date.substring(0, 6); //本月
        int count2 = ordersRepository.monthPayCount(userId, month);
        //本月付款金额
        Double count3 = ordersRepository.monthPayNumber(userId, month);
        //上月付款金额
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.MONTH, -1); //获取上个月的日期（上个月的今天）
        Date date3 = cal.getTime();
        String lastMonth = sdf.format(date3);
        Double count4 = ordersRepository.lastMonthPayNumber(userId, lastMonth);
        map.put("count1", count1);
        map.put("count2", count2);
        map.put("count3", count3 == null ? 0 : count3);
        map.put("count4", count4 == null ? 0 : count4);
        return ResultUtil.success(map);
    }

    /**
     * 订单数量统计
     *
     * @param userId
     * @return
     */
    @Override
    public Result count(Long userId) {
        Map<String, Object> map = new HashMap<>();
        int count1 = 0;
        int count2 = 0;
        int count3 = 0;
        int count4 = 0;
        int count5 = 0;
        //订单状态（1待付款 2已付款 3已发货 4已收货 5已取消 6退款中 7已退款 8拒绝退款 9拼团中 10已评价）
        List<Orders> list = ordersRepository.findByUserId(userId);
        for (Orders o : list) {
            switch (o.getStatus()) {
                case 1:
                    count1++;
                    break;
                case 2:
                    count2++;
                    break;
                case 3:
                    count3++;
                    break;
                case 4:
                    count4++;
                    break;
                case 6:
                    count5++;
                    break;
            }
        }
        map.put("count1", count1); //待付款
        map.put("count2", count2); //代发货
        map.put("count3", count3); //待收货
        map.put("count4", count4); //待评价
        map.put("count5", count5); //退款
        return ResultUtil.success(map);
    }

    @Override
    public Result findExpress(String expressNumber) {
        String appCode = commonRepository.findOne(94).getValue();
        String host = "https://wuliu.market.alicloudapi.com";// 【1】请求地址 支持http 和 https 及 WEBSOCKET
        String path = "/kdi";  // 【2】后缀
        String appcode = appCode; // 【3】开通服务后 买家中心-查看AppCode
        String no = expressNumber.trim();// 【4】请求参数，详见文档描述
        String type = ""; //  【4】请求参数，不知道可不填 95%能自动识别
        String urlSend = host + path + "?no=" + no + "&type=" + type;  // 【5】拼接请求链接
        try {
            URL url = new URL(urlSend);
            HttpURLConnection httpURLCon = (HttpURLConnection) url.openConnection();
            httpURLCon.setRequestProperty("Authorization", "APPCODE " + appcode);// 格式Authorization:APPCODE (中间是英文空格)
            int httpCode = httpURLCon.getResponseCode();
            if (httpCode == 200) {
                String json = read(httpURLCon.getInputStream());
                return ResultUtil.success(JSON.parseObject(json));
            } else {
                Map<String, List<String>> map = httpURLCon.getHeaderFields();
                String error = map.get("X-Ca-Error-Message").get(0);
                if (httpCode == 400 && error.equals("Invalid AppCode `not exists`")) {
                    System.out.println("AppCode错误 ");
                } else if (httpCode == 400 && error.equals("Invalid Url")) {
                    System.out.println("请求的 Method、Path 或者环境错误");
                } else if (httpCode == 400 && error.equals("Invalid Param Location")) {
                    System.out.println("参数错误");
                } else if (httpCode == 403 && error.equals("Unauthorized")) {
                    System.out.println("服务未被授权（或URL和Path不正确）");
                } else if (httpCode == 403 && error.equals("Quota Exhausted")) {
                    System.out.println("套餐包次数用完 ");
                } else {
                    System.out.println("参数名错误 或 其他错误");
                    System.out.println(error);
                }
            }
        } catch (MalformedURLException e) {
            System.out.println("URL格式错误");
        } catch (UnknownHostException e) {
            System.out.println("URL地址错误");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.error(-1, "查询失败");
    }

    /*
     * 读取返回结果
     */
    private static String read(InputStream is) throws IOException {
        StringBuffer sb = new StringBuffer();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = null;
        while ((line = br.readLine()) != null) {
            line = new String(line.getBytes(), "utf-8");
            sb.append(line);
        }
        br.close();
        return sb.toString();
    }

    /**
     * 核销订单
     *
     * @param orderNum
     * @return
     */
    @Override
    public Result isExpress(String orderNum) {
        Orders orders = jpaRepository.findByOrderNum(orderNum);
        if (orders == null) {
            return ResultUtil.error(-1, "核销码不存在");
        }
        orders.setStatus(4); //已使用、待评价
        orders.setExpressTime(DateUtil.createTime());
        orders.setFinishTime(DateUtil.createTime()); //使用时间
        jpaRepository.save(orders);
        return ResultUtil.success();
    }

    /**
     * 购物车订单BUG:取消订单、返还优惠券
     *
     * @param list
     * @return
     */
    @Override
    public void cancel(List<Orders> list) {
        for (Orders orders : list) {
            if (orders.getStatus() == 1) {
                orders.setStatus(5);
                jpaRepository.save(orders);
                //sku库存+1
                skuService.addStock(orders.getSkuId(), orders.getNumber());
                //优惠券
                if (orders.getUserCouponsId() != null) {
                    couponUserJpaRepository.backCoupon(orders.getUserCouponsId());
                }
            }
        }
    }

    @Override
    public List<Orders> findEffectByUserId(Long userId, Long typeId) {
        List<Orders> effectByUserId = ordersRepository.findEffectByUserId(userId);
        if(typeId != null) {
            return effectByUserId.stream().filter(e -> typeId.equals(e.getType())).collect(Collectors.toList());
        }
        return effectByUserId;
    }

    @Override
    public DeductPointRes queryDeductPoint(Long goodsId) {
        UserInfo userInfo = LoginUserHolder.getUserInfo();
        AssertUtil.assertTrue(userInfo != null && userInfo.getId() > 0, ExceptionEnum.WRONT_TOKEN);
        // 查询商品信息
        Goods g = goodsJpaRepository.findById(goodsId).orElse(null);
        AssertUtil.assertTrue(g != null && g.getStatus() == 1, ExceptionEnum.GOODS_NOT_AVAILABLE);
        DeductPointRes deductPointRes = new DeductPointRes();
        deductPointRes.setGoodsPrice(g.getPrice());
        if (!partnerTypeId.equals(g.getTypeId())) {
            return deductPointRes;
        }

        List<OrderPartnerInfo> myPartners = partnerService.queryUserPartnerList(userInfo.getId(), Long.valueOf(partnerTypeId));
        // 登录用户不是合伙人
        if(CollectionUtils.isEmpty(myPartners)) {
            return deductPointRes;
        }
        BigDecimal userPoint = userInfo.getPromotePointAvailable();
        deductPointRes.setPartnerFlag(true);
        deductPointRes.setPromotePointAvailable(userPoint);
        // 查询之前下了第几单
        List<OrderPartnerInfo> orders = partnerService.queryUserPartnerOrders(userInfo.getId(), Long.valueOf(partnerTypeId));
        int count = orders.size();
        deductPointRes.setOrderCounts(count);
        // 计算当前抵扣比例，按周期循环，如:0.2,0.25,0.55
        String[] percents = percentList.trim().split(",");
        int index = count % percents.length;
        BigDecimal percent = new BigDecimal(percents[index].trim());
        deductPointRes.setDeductPercent(percent);
        //
        BigDecimal goodsPoint = g.getPrice().multiply(percent);
        BigDecimal deductPoint = userPoint.compareTo(goodsPoint) > 0 ? goodsPoint : userPoint;
        deductPointRes.setDeductPoint(new BigDecimal(deductPoint.intValue()));
        log.info("查询可抵积分数，返回信息为:{}", JsonUtils.toJsonString(deductPointRes));
        return deductPointRes;
    }
}
